﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using MediaLibraryManager;
using System.Globalization;
using System.IO;

namespace MediaLibraryManager.Service
{
    public partial class Service : ServiceBase
	{
		private List<MediaFileSystemWatcher> watchers;
		private MediaLibraryApplicationContext appContext;

        public Service()
        {
			InitializeComponent();

			//Uncomment this line to have time to attach the process for debuging.
			//System.Threading.Thread.Sleep(25000);

			try
			{
				appContext = new MediaLibraryApplicationContext(
					SourceApplication.WatcherService,
					this.DesignMode);
				
				this.watchers = new List<MediaFileSystemWatcher>();
				AddWatchers(MediaType.MusicVideo);
				AddWatchers(MediaType.PersonalVideo);
				AddWatchers(MediaType.PrivateVideo);
				AddWatchers(MediaType.TVRecording);
				AddWatchers(MediaType.OtherVideo);
				AddWatchers(MediaType.Picture);
				AddWatchers(MediaType.PrivatePicture);
				AddWatchers(MediaType.Music);
			}
			catch (Exception ex)
			{
				WriteLogException(ex,null);
				throw ex;
			}
		}

		protected override void OnStart(string[] args)
		{
			foreach (MediaFileSystemWatcher watcher in this.watchers)
				watcher.EnableRaisingEvents = true;

			WriteLogEntry("Process started succesfully");
		}

		protected override void OnStop()
		{
			foreach (MediaFileSystemWatcher watcher in this.watchers)
				watcher.EnableRaisingEvents = false;

			WriteLogEntry("Process stopped succesfully");
		}

		private void AddWatchers(MediaType mediaType)
		{
			string paths = appContext.Parameters[String.Format("{0}MonitoredPaths", mediaType.ToString())];

			foreach (string path in paths.Split(';'))
			{
				if (path != String.Empty)
				{
					MediaFileSystemWatcher watcher = new MediaFileSystemWatcher();
					((ISupportInitialize)(watcher)).BeginInit();
					watcher.Path = path;
					watcher.MediaType = mediaType;

					if (appContext.Parameters["WatchersInternalBufferSize"] != string.Empty)
						watcher.InternalBufferSize =
							Convert.ToInt32(appContext.Parameters["WatchersInternalBufferSize"],
								CultureInfo.CurrentUICulture);

					watcher.NotifyFilter = NotifyFilters.CreationTime | NotifyFilters.LastWrite | NotifyFilters.FileName;
					watcher.MediaRenamed += new MediaRenamedEventHandler(this.fileSystemWatcher_Renamed);
					watcher.MediaDeleted += new MediaFileSystemEventHandler(this.fileSystemWatcher_Deleted);
					watcher.MediaCreated += new MediaFileSystemEventHandler(this.fileSystemWatcher_Created);
					((ISupportInitialize)(watcher)).EndInit();
					this.watchers.Add(watcher);
				}
			}
		}

		private void fileSystemWatcher_Created(object sender, MediaFileSystemEventArgs e)
		{
			appContext.CreateMedia(e.Name, e.FullPath, e.MediaType);
		}

		private void fileSystemWatcher_Deleted(object sender, MediaFileSystemEventArgs e)
		{
			appContext.DeleteMedia(e.Name, e.FullPath, e.MediaType);
		}

		private void fileSystemWatcher_Renamed(object sender, MediaRenamedEventArgs e)
		{
			appContext.RenameMedia(e.Name,e.OldFullPath,e.FullPath,e.MediaType);
		}

		private void WriteLogEntry(string message)
		{
			appContext.WriteLogEntry(message);
		}

		private void WriteLogException(Exception e, string filePath)
		{
			appContext.WriteLogException(e, filePath);
		}
    }
}
